package com.jiangli.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jiangli.dto.SysOperationLogQueryDTO;
import com.jiangli.entity.SysOperationLog;
import com.jiangli.mapper.SysOperationLogMapper;
import com.jiangli.result.PageResult;
import com.jiangli.vo.FeedbackVO;
import com.jiangli.vo.SysOperationLogVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Service
@Slf4j
public class SysOperationLogService {

    @Autowired
    private SysOperationLogMapper logMapper;
    @Autowired
    private SysOperationLogMapper sysOperationLogMapper;

    // 线程池配置，专门用于处理日志保存
    @Bean
    public Executor logExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数
        executor.setCorePoolSize(2);
        // 最大线程数
        executor.setMaxPoolSize(5);
        // 队列容量
        executor.setQueueCapacity(100);
        // 线程名称前缀
        executor.setThreadNamePrefix("log-save-");
        // 拒绝策略：当任务过多时，由提交任务的线程处理
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 初始化
        executor.initialize();
        return executor;
    }

    /**
     * 异步保存日志，带有重试机制
     */
    @Async("logExecutor") // 指定使用上面配置的线程池
    public void asyncSaveLog(SysOperationLog SLog) {
        int maxRetries = 3; // 最大重试次数
        int retryCount = 0;

        while (retryCount < maxRetries) {
            try {
                logMapper.insert(SLog);
                log.info("日志保存成功，操作: {}", SLog.getOperation());
                return; // 保存成功，退出方法
            } catch (Exception e) {
                retryCount++;
                log.error("日志保存失败，第{}次重试，错误: {}", retryCount, e.getMessage());

                // 如果还没到最大重试次数，休眠一段时间再重试
                if (retryCount < maxRetries) {
                    try {
                        Thread.sleep(100L * retryCount); // 指数退避策略
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }
        }

    }

    public PageResult getSysOperation(SysOperationLogQueryDTO sysOperationLogQueryDTO) {
        PageHelper.startPage(Math.toIntExact(sysOperationLogQueryDTO.getPage()), Math.toIntExact(sysOperationLogQueryDTO.getPageSize()));
        Page<SysOperationLogVO> page = sysOperationLogMapper.get(sysOperationLogQueryDTO);
        PageResult pageResult = new PageResult();
        pageResult.setTotal(page.getTotal());
        pageResult.setRecords(page.getResult());
        return pageResult;
    }
}
